home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / vidhrdw / rpunch.c < prev    next >
C/C++ Source or Header  |  2000-05-04  |  12KB  |  502 lines

  1. /***************************************************************************
  2.  
  3.   vidhrdw/rpunch.c
  4.  
  5.   Functions to emulate the video hardware of the machine.
  6.  
  7. ****************************************************************************/
  8.  
  9. #ifndef INCLUDE_DRAW_CORE
  10.  
  11. #include "driver.h"
  12. #include "vidhrdw/generic.h"
  13.  
  14.  
  15. #define BITMAP_WIDTH    304
  16. #define BITMAP_HEIGHT    224
  17. #define BITMAP_XOFFSET    4
  18.  
  19.  
  20. /*************************************
  21.  *
  22.  *    Statics
  23.  *
  24.  *************************************/
  25.  
  26. UINT8 *rpunch_bitmapram;
  27. size_t rpunch_bitmapram_size;
  28. static UINT32 *rpunch_bitmapsum;
  29.  
  30. int rpunch_sprite_palette;
  31.  
  32. static struct tilemap *background[2];
  33.  
  34. static UINT16 videoflags;
  35. static UINT8 crtc_register;
  36. static void *crtc_timer;
  37. static UINT8 bins, gins;
  38.  
  39. static const UINT16 *callback_videoram;
  40. static UINT8 callback_gfxbank;
  41. static UINT8 callback_colorbase;
  42. static UINT16 callback_imagebase;
  43. static UINT16 callback_imagemask;
  44.  
  45.  
  46. /*************************************
  47.  *
  48.  *    Prototypes
  49.  *
  50.  *************************************/
  51.  
  52. void rpunch_vh_stop(void);
  53.  
  54. static void draw_bitmap_8(struct osd_bitmap *bitmap);
  55. static void draw_bitmap_16(struct osd_bitmap *bitmap);
  56.  
  57.  
  58.  
  59. /*************************************
  60.  *
  61.  *    Tilemap callbacks
  62.  *
  63.  *************************************/
  64.  
  65. static void get_bg_tile_info(int tile_index)
  66. {
  67.     int data = callback_videoram[tile_index];
  68.     SET_TILE_INFO(callback_gfxbank,
  69.             callback_imagebase | (data & callback_imagemask),
  70.             callback_colorbase | ((data >> 13) & 7));
  71. }
  72.  
  73.  
  74.  
  75. /*************************************
  76.  *
  77.  *    Video system start
  78.  *
  79.  *************************************/
  80.  
  81. static void crtc_interrupt_gen(int param)
  82. {
  83.     cpu_cause_interrupt(0, 1);
  84.     if (param != 0)
  85.         crtc_timer = timer_pulse(TIME_IN_HZ(Machine->drv->frames_per_second * param), 0, crtc_interrupt_gen);
  86. }
  87.  
  88.  
  89. int rpunch_vh_start(void)
  90. {
  91.     int i;
  92.  
  93.     /* allocate tilemaps for the backgrounds and a bitmap for the direct-mapped bitmap */
  94.     background[0] = tilemap_create(get_bg_tile_info,tilemap_scan_cols,TILEMAP_OPAQUE,     8,8,64,64);
  95.     background[1] = tilemap_create(get_bg_tile_info,tilemap_scan_cols,TILEMAP_TRANSPARENT,8,8,64,64);
  96.  
  97.     /* allocate a bitmap sum */
  98.     rpunch_bitmapsum = malloc(BITMAP_HEIGHT * sizeof(UINT32));
  99.  
  100.     /* if anything failed, clean up and return an error */
  101.     if (!background[0] || !background[1] || !rpunch_bitmapsum)
  102.     {
  103.         rpunch_vh_stop();
  104.         return 1;
  105.     }
  106.  
  107.     /* configure the tilemaps */
  108.     background[1]->transparent_pen = 15;
  109.  
  110.     /* reset the sums and bitmap */
  111.     for (i = 0; i < BITMAP_HEIGHT; i++)
  112.         rpunch_bitmapsum[i] = (BITMAP_WIDTH/4) * 0xffff;
  113.     if (rpunch_bitmapram)
  114.         memset(rpunch_bitmapram, 0xff, rpunch_bitmapram_size);
  115.  
  116.     /* reset the timer */
  117.     crtc_timer = NULL;
  118.     return 0;
  119. }
  120.  
  121.  
  122.  
  123. /*************************************
  124.  *
  125.  *    Video system shutdown
  126.  *
  127.  *************************************/
  128.  
  129. void rpunch_vh_stop(void)
  130. {
  131.     if (rpunch_bitmapsum)
  132.         free(rpunch_bitmapsum);
  133.     rpunch_bitmapsum = NULL;
  134. }
  135.  
  136.  
  137.  
  138. /*************************************
  139.  *
  140.  *        Write handlers
  141.  *
  142.  *************************************/
  143.  
  144. WRITE_HANDLER(rpunch_bitmap_w)
  145. {
  146.     if (rpunch_bitmapram)
  147.     {
  148.         int oldword = READ_WORD(&rpunch_bitmapram[offset]);
  149.         int newword = COMBINE_WORD(oldword, data);
  150.         if (oldword != newword)
  151.         {
  152.             int row = offset / 256;
  153.             int col = 2 * (offset % 256) - BITMAP_XOFFSET;
  154.             WRITE_WORD(&rpunch_bitmapram[offset], data);
  155.             if (row < BITMAP_HEIGHT && col >= 0 && col < BITMAP_WIDTH)
  156.                 rpunch_bitmapsum[row] += newword - oldword;
  157.         }
  158.     }
  159. }
  160.  
  161.  
  162. WRITE_HANDLER(rpunch_videoram_w)
  163. {
  164.     int oldword = READ_WORD(&videoram[offset]);
  165.     int newword = COMBINE_WORD(oldword, data);
  166.     if (oldword != newword)
  167.     {
  168.         int tilemap = offset >> 13;
  169.         int tile_index = (offset / 2) & 0xfff;
  170.         WRITE_WORD(&videoram[offset], newword);
  171.         tilemap_mark_tile_dirty(background[tilemap],tile_index);
  172.     }
  173. }
  174.  
  175.  
  176. WRITE_HANDLER(rpunch_videoreg_w)
  177. {
  178.     int newword = COMBINE_WORD(videoflags, data);
  179.     if (videoflags != newword)
  180.     {
  181.         /* invalidate tilemaps */
  182.         if ((newword ^ videoflags) & 0x0410)
  183.             tilemap_mark_all_tiles_dirty(background[0]);
  184.         if ((newword ^ videoflags) & 0x0820)
  185.             tilemap_mark_all_tiles_dirty(background[1]);
  186.         videoflags = newword;
  187.     }
  188. }
  189.  
  190.  
  191. WRITE_HANDLER(rpunch_scrollreg_w)
  192. {
  193.     switch (offset / 2)
  194.     {
  195.         case 0:
  196.             tilemap_set_scrolly(background[0], 0, data & 0x1ff);
  197.             break;
  198.  
  199.         case 1:
  200.             tilemap_set_scrollx(background[0], 0, (data & 0x1ff) - 8);
  201.             break;
  202.  
  203.         case 2:
  204.             tilemap_set_scrolly(background[1], 0, data & 0x1ff);
  205.             break;
  206.  
  207.         case 3:
  208.             tilemap_set_scrollx(background[1], 0, data & 0x1ff);
  209.             break;
  210.     }
  211. }
  212.  
  213.  
  214. WRITE_HANDLER(rpunch_crtc_data_w)
  215. {
  216.     if (!(data & 0x00ff0000))
  217.     {
  218.         data &= 0xff;
  219.         switch (crtc_register)
  220.         {
  221.             /* only register we know about.... */
  222.             case 0x0b:
  223.                 if (crtc_timer)
  224.                     timer_remove(crtc_timer);
  225.                 crtc_timer = timer_set(cpu_getscanlinetime(Machine->drv->visible_area.max_y + 1), (data == 0xc0) ? 2 : 1, crtc_interrupt_gen);
  226.                 break;
  227.  
  228.             default:
  229.                 logerror("CRTC register %02X = %02X\n", crtc_register, data & 0xff);
  230.                 break;
  231.         }
  232.     }
  233. }
  234.  
  235.  
  236. WRITE_HANDLER(rpunch_crtc_register_w)
  237. {
  238.     if (!(data & 0x00ff0000))
  239.         crtc_register = data & 0xff;
  240. }
  241.  
  242.  
  243. WRITE_HANDLER(rpunch_ins_w)
  244. {
  245.     if (!(data & 0x00ff0000))
  246.     {
  247.         if (offset == 0)
  248.         {
  249.             gins = data & 0x3f;
  250.             logerror("GINS = %02X\n", data & 0x3f);
  251.         }
  252.         else
  253.         {
  254.             bins = data & 0x3f;
  255.             logerror("BINS = %02X\n", data & 0x3f);
  256.         }
  257.     }
  258. }
  259.  
  260.  
  261. /*************************************
  262.  *
  263.  *        Sprite routines
  264.  *
  265.  *************************************/
  266.  
  267. static void mark_sprite_palette(void)
  268. {
  269.     UINT16 used_colors[16];
  270.     int offs, i, j;
  271.  
  272.     memset(used_colors, 0, sizeof(used_colors));
  273.     for (offs = 0; offs < spriteram_size; offs += 8)
  274.     {
  275.         int data1 = READ_WORD(&spriteram[offs + 2]);
  276.         int code = data1 & 0x7ff;
  277.  
  278.         if (code < 0x600)
  279.         {
  280.             int data0 = READ_WORD(&spriteram[offs + 0]);
  281.             int data2 = READ_WORD(&spriteram[offs + 4]);
  282.             int x = (data2 & 0x1ff) + 8;
  283.             int y = 513 - (data0 & 0x1ff);
  284.             int color = ((data1 >> 13) & 7) | ((videoflags & 0x0040) >> 3);
  285.  
  286.             if (x >= BITMAP_WIDTH) x -= 512;
  287.             if (y >= BITMAP_HEIGHT) y -= 512;
  288.  
  289.             if (x > -16 && y > -32)
  290.                 used_colors[color] |= Machine->gfx[2]->pen_usage[code];
  291.         }
  292.     }
  293.  
  294.     for (i = 0; i < 16; i++)
  295.     {
  296.         UINT16 used = used_colors[i];
  297.         if (used)
  298.         {
  299.             for (j = 0; j < 15; j++)
  300.                 if (used & (1 << j))
  301.                     palette_used_colors[rpunch_sprite_palette + i * 16 + j] = PALETTE_COLOR_USED;
  302.             palette_used_colors[rpunch_sprite_palette + i * 16 + 15] = PALETTE_COLOR_TRANSPARENT;
  303.         }
  304.     }
  305. }
  306.  
  307.  
  308. static void draw_sprites(struct osd_bitmap *bitmap)
  309. {
  310.     int offs;
  311.  
  312.     /* draw the sprites */
  313.     for (offs = 0; offs < spriteram_size; offs += 8)
  314.     {
  315.         int data1 = READ_WORD(&spriteram[offs + 2]);
  316.         int code = data1 & 0x7ff;
  317.  
  318.         if (code < 0x600)
  319.         {
  320.             int data0 = READ_WORD(&spriteram[offs + 0]);
  321.             int data2 = READ_WORD(&spriteram[offs + 4]);
  322.             int x = (data2 & 0x1ff) + 8;
  323.             int y = 513 - (data0 & 0x1ff);
  324.             int xflip = data1 & 0x1000;
  325.             int color = ((data1 >> 13) & 7) | ((videoflags & 0x0040) >> 3);
  326.  
  327.             if (x >= BITMAP_WIDTH) x -= 512;
  328.             if (y >= BITMAP_HEIGHT) y -= 512;
  329.  
  330.             drawgfx(bitmap, Machine->gfx[2],
  331.                     code, color + (rpunch_sprite_palette / 16), xflip, 0, x, y, 0, TRANSPARENCY_PEN, 15);
  332.         }
  333.     }
  334. }
  335.  
  336.  
  337. /*************************************
  338.  *
  339.  *        Main screen refresh
  340.  *
  341.  *************************************/
  342.  
  343. void rpunch_vh_screenrefresh(struct osd_bitmap *bitmap, int full_refresh)
  344. {
  345.     int x, penbase;
  346.  
  347.     /* update background 0 */
  348.     callback_gfxbank = 0;
  349.     callback_videoram = (const UINT16 *)&videoram[0];
  350.     callback_colorbase = (videoflags & 0x0010) >> 1;
  351.     callback_imagebase = (videoflags & 0x0400) << 3;
  352.     callback_imagemask = callback_imagebase ? 0x0fff : 0x1fff;
  353.     tilemap_update(background[0]);
  354.  
  355.     /* update background 1 */
  356.     callback_gfxbank = 1;
  357.     callback_videoram = (const UINT16 *)&videoram[videoram_size / 2];
  358.     callback_colorbase = (videoflags & 0x0020) >> 2;
  359.     callback_imagebase = (videoflags & 0x0800) << 2;
  360.     callback_imagemask = callback_imagebase ? 0x0fff : 0x1fff;
  361.     tilemap_update(background[1]);
  362.  
  363.     /* update the palette usage */
  364.     palette_init_used_colors();
  365.     mark_sprite_palette();
  366.     if (rpunch_bitmapram)
  367.     {
  368.         penbase = 512 + (videoflags & 15);
  369.         for (x = 0; x < 15; x++)
  370.             palette_used_colors[penbase + x] = PALETTE_COLOR_USED;
  371.         palette_used_colors[penbase + 15] = PALETTE_COLOR_TRANSPARENT;
  372.     }
  373.  
  374.     /* handle full refresh */
  375.     if (palette_recalc() || full_refresh)
  376.         tilemap_mark_all_pixels_dirty(ALL_TILEMAPS);
  377.  
  378.     /* update the tilemaps */
  379.     tilemap_render(ALL_TILEMAPS);
  380.  
  381.     /* build the result */
  382.     tilemap_draw(bitmap, background[0], 0);
  383.  
  384.     /* if we have a bitmap layer, it goes on top */
  385.     if (rpunch_bitmapram)
  386.     {
  387.         tilemap_draw(bitmap, background[1], 0);
  388.         draw_sprites(bitmap);
  389.         if (bitmap->depth == 8)
  390.             draw_bitmap_8(bitmap);
  391.         else
  392.             draw_bitmap_16(bitmap);
  393.     }
  394.  
  395.     /* otherwise, the second background layer gets top billing */
  396.     else
  397.     {
  398.         draw_sprites(bitmap);
  399.         tilemap_draw(bitmap, background[1], 0);
  400.     }
  401. }
  402.  
  403.  
  404.  
  405. /*************************************
  406.  *
  407.  *        Depth-specific refresh
  408.  *
  409.  *************************************/
  410.  
  411. #define ADJUST_FOR_ORIENTATION(orientation, bitmap, dst, x, y, xadv)    \
  412.     if (orientation)                                                    \
  413.     {                                                                    \
  414.         int dy = bitmap->line[1] - bitmap->line[0];                        \
  415.         int tx = x, ty = y, temp;                                        \
  416.         if (orientation & ORIENTATION_SWAP_XY)                            \
  417.         {                                                                \
  418.             temp = tx; tx = ty; ty = temp;                                \
  419.             xadv = dy / (bitmap->depth / 8);                            \
  420.         }                                                                \
  421.         if (orientation & ORIENTATION_FLIP_X)                            \
  422.         {                                                                \
  423.             tx = bitmap->width - 1 - tx;                                \
  424.             if (!(orientation & ORIENTATION_SWAP_XY)) xadv = -xadv;        \
  425.         }                                                                \
  426.         if (orientation & ORIENTATION_FLIP_Y)                            \
  427.         {                                                                \
  428.             ty = bitmap->height - 1 - ty;                                \
  429.             if ((orientation & ORIENTATION_SWAP_XY)) xadv = -xadv;        \
  430.         }                                                                \
  431.         /* can't lookup line because it may be negative! */                \
  432.         dst = (TYPE *)(bitmap->line[0] + dy * ty) + tx;                    \
  433.     }
  434.  
  435. #define INCLUDE_DRAW_CORE
  436.  
  437. #define DRAW_FUNC draw_bitmap_8
  438. #define TYPE UINT8
  439. #include "rpunch.c"
  440. #undef TYPE
  441. #undef DRAW_FUNC
  442.  
  443. #define DRAW_FUNC draw_bitmap_16
  444. #define TYPE UINT16
  445. #include "rpunch.c"
  446. #undef TYPE
  447. #undef DRAW_FUNC
  448.  
  449.  
  450. #else
  451.  
  452.  
  453. /*************************************
  454.  *
  455.  *        Core refresh routine
  456.  *
  457.  *************************************/
  458.  
  459. void DRAW_FUNC(struct osd_bitmap *bitmap)
  460. {
  461.     UINT16 *pens = &Machine->pens[512 + (videoflags & 15) * 16];
  462.     int orientation = Machine->orientation;
  463.     int x, y;
  464.  
  465.     /* draw any non-transparent scanlines from the VRAM directly */
  466.     for (y = 0; y < BITMAP_HEIGHT; y++)
  467.         if (rpunch_bitmapsum[y] != (BITMAP_WIDTH/4) * 0xffff)
  468.         {
  469.             UINT16 *src = (UINT16 *)&rpunch_bitmapram[y * 256 + BITMAP_XOFFSET/2];
  470.             TYPE *dst = (TYPE *)bitmap->line[y];
  471.             int xadv = 1;
  472.  
  473.             /* adjust in case we're oddly oriented */
  474.             ADJUST_FOR_ORIENTATION(orientation, bitmap, dst, 0, y, xadv);
  475.  
  476.             /* redraw the scanline */
  477.             for (x = 0; x < BITMAP_WIDTH/4; x++)
  478.             {
  479.                 int data = *src++;
  480.                 if (data != 0xffff)
  481.                 {
  482.                     if ((data & 0xf000) != 0xf000)
  483.                         *dst = pens[data >> 12];
  484.                     dst += xadv;
  485.                     if ((data & 0x0f00) != 0x0f00)
  486.                         *dst = pens[(data >> 8) & 15];
  487.                     dst += xadv;
  488.                     if ((data & 0x00f0) != 0x00f0)
  489.                         *dst = pens[(data >> 4) & 15];
  490.                     dst += xadv;
  491.                     if ((data & 0x000f) != 0x000f)
  492.                         *dst = pens[data & 15];
  493.                     dst += xadv;
  494.                 }
  495.                 else
  496.                     dst += 4 * xadv;
  497.             }
  498.         }
  499. }
  500.  
  501. #endif
  502.